
/**
 * @desc 封装了本地（local）和远程(Server)两种请求，并自动匹配API 请求方法(GET,POST)
 * @copyright redmicro all Copyright (c)
 * @author Created by seeker910 on 14-3-17.
 * @memberof Rsd.data
 */
Rsd.define('Rsd.data.Service',{
    extend:'Rsd.common.Object',
    xtype:'service',
    name:'',
    text:'',
    timeout:0,
    msg:null,
    isDemo:false,
    //server:{},
    //local:{},
    failureHandler:null,
    successHandler:null,
    errorHandler:null,
    completeHandler:null,
    /**
     * @constructs Rsd.data.Service
     * @classdesc Rsd.common.Service用于对业务接口的对象化管理，并且同时提供本地（local）和远程(Server)两种方式的请求;负责远程远程或本地服务调用;将远程服务与本地ajax请求逻辑合并封装
     *
     * @property  {string} extend Rsd.common.Object
     * @property  {string} xtype service
     * @property {string|function} failureHandler 服务请求业务处理失败时事件处理
     * @property {string|function} successHandler 服务请求业务处理成功时事件处理
     * @property {string|function} errorHandler 服务请求发生错误时事件处理
     * @property {string|function} completeHandler 服务请求完成事件处理
     * @property {object} local 格式：{ method:'get',url:''},
     * @property {object } server 格式：{ method:'get',url:''}
     * @property  {boolean} isDemo 是demo版本
     * @property  {string} name 英文名称
     * @property  {string} text 中文名称
     * @property  {int} timeout 超时时间
     * @property  {string} msg 进度条文字
     * * */
    constructor: function Service(config) {
        //debugger;
        config = config || {};
        this.apply(config);
    },
    /**
     * @description 事件注册
     * @public
     * @function
     * @memberof Rsd.data.Ajax
     * */
    on: function on(name, fn) {

        if (!name || name == '') {
            throw new Error('argument \'name\' is null.');
        }
        if (!fn || typeof (fn) != 'function') {
            throw new Error('on ['+name+'] event failed ,argument \'fn\' is not a function object.');
        }
        //var me = this;

        this.events.add(this, name, fn);
    },
    /**
     * @description 触发事件
     * @aram name ：名称
     * @aram  args :数组
     */
    fire:function fire(name,args)
    {
        if (!name || name == '') {
            throw new Error('argument \'name\' is null.');
        }
       
        this.events.fire(this, name, args);
    },
    /**
     *
     * @description 远程测试,支持批量数据测试
     * @function
     * @public
     * @memberof Rsd.data.Service
     * */
    testServer:function testServer(args){
        //debugger;
        var me =this;
        var _args =  args||me.args||[];
        if( _args.length == 0)
        {
            Rsd.debug('Testing:'+me.server.url);
            Rsd.httpRequest(this.server,{},function (data) {
                Rsd.log(data);
            });
        }
        else  {
            for(var data in _args) {
                Rsd.debug('Testing:'+me.server.url+";args:"+data);
                Rsd.httpRequest(me.server,data,null);
            }
        }
    },
    /**
     * @description 本地模拟数据测试
     * @function
     * @public
     * @memberof Rsd.data.Service
     * */
    testLocal:function testLocal()
    {
        Rsd.httpRequest(this.local,{},null);
    },

    /**
     * @private
     * @function
     * @memberof Rsd.data.Service
     * @description ajax 请求完成时执行
     * */
    complete:function complete(response)
    {
        if(Rsd.isFunction(this.completeHandler))
        {
            return this.completeHandler.call(this,response);
        }
        if(Rsd.isString(this.completeHandler)&& this.completeHandler !='')
        {
            return this.funApplyByIOC(this.completeHandler,arguments);
        }
        return true;
    },
    /** 
     * @private
     * @function
     * @memberof Rsd.data.Service
     * @description 业务逻辑成功：ajax请求成功，返回json数据中,success==true时执行
    * */
    success : function(response) {

        if (Rsd.isFunction(this.successHandler)) {
            return this.successHandler.call(this, response);
        }
        if (Rsd.isString(this.successHandler) && this.successHandler !='') {
            return this.funApplyByIOC(this.successHandler, arguments);
        }
        return true;
    },
    /**
     * @private
     * @function
     * @memberof Rsd.data.Service
     * @description 业务逻辑错误：ajax请求成功，返回json数据中,success==flase时执行
     * */
    failure:function failure(data)
    {
        if (Rsd.isFunction(this.failureHandler)) {
            return this.failureHandler.call(this, data);
        }
        if (Rsd.isString(this.failureHandler) && this.failureHandler !='') {
            return this.funApplyByIOC(this.failureHandler, arguments);
        }

        return true;
    },
    
    /**
     * @private
     * @function
     * @memberof Rsd.data.Service
     * @description ajax请求失败时执行，如：网络不通
     * */
    error:function error(xhr, textStatus, error){

        if(Rsd.isFunction(this.errorHandler))
        {
            return this.errorHandler.call(this,xhr, textStatus, error);
        }
        if(Rsd.isString(this.errorHandler)&& this.errorHandler !='')
        {
            return this.funApplyByIOC(this.errorHandler,arguments);
        }
        return true;
    },
     
    /**
     * @public
     * @function
     * @memberof Rsd.data.Service
     * @param {object} data 作为Ajax对象请求时的参数中data属性（即远程方法的参数）
     * @param {function} callback 优先执行callback，返回true时,后续方法（success,failure）继续执行，返回false时，后续方法终止。
     * @param {string} msg 提示信息
     * @param {number} timeout 超时时长（毫秒）
     * @param {object} routeArgs 路由参数
    * */
    request:function request(data,callback,msg,timeout,routeArgs) {
       
        data = data||{};
        var _routeArgs = routeArgs||data||{};
        var _timeout = timeout||this.timeout||null;
        var _msg = msg||this.msg||null;
        
        var me = this; 
         //msg 提示信息 
         var _waitingId = null;
         //console.log(_msg,_timeout);
         if(_msg)
         {
           _waitingId = Rsd.showWaiting(me.id,Rsd,_msg);
           
           setTimeout(function(){
               Rsd.closeWaiting(_waitingId);
               _waitingId=0;
           },_timeout||5000);
 
         }
         //执行ajax 请求后回调方法
        var _callback=function(_data){
            //debugger; 
            var _b = true; 
            //优先执行callback
            if(_b && Rsd.isFunction(callback) )
            {
                _b = callback.call(me,_data);
            }
            if(_b == undefined )
            {
                _b = true;
            }
            if( _b == false || _b == 0 || _b < 0 || _b == null)
            {
                if(_waitingId)
                {
                    Rsd.closeWaiting(_waitingId);
                }
                return false;//后续方法不在执行
            }
            //处理对象 属性方法
            if(_data && !_data.success)
            {
                me.failure(_data);
            }
            else
            {
                //Service 自身success 处理
                me.success(_data);
            }

            if(_waitingId)
            {
                Rsd.closeWaiting(_waitingId);
            }
        };
         //debugger;
        if(this.isDemo){

            var _ajax = Rsd.create('Rsd.data.Ajax',Rsd.apply( {
                    token:Rsd.getAppToken(),
                    appId:Rsd.getAppId(),
                    authCode:Rsd.getAppAuthorization(),
                    jsonFormatter:Rsd.getAppConfig('jsonFormatter'),
                    complete:function _complete(){ if(_waitingId)Rsd.closeWaiting(_waitingId);me.complete.apply(me,arguments);},
                    error:function _error(){ if(_waitingId)Rsd.closeWaiting(_waitingId);me.error.apply(me,arguments);}
                },this.local));

            if(_timeout)
            { 
                _ajax.timeout = _timeout;
            }

            var _fn = function (_data) {
                var _name = Rsd.getUrlParam(_ajax.url,'name');
                _callback(_data[_name]); 
            }

            return _ajax.request(data,_fn);
        }
        else
        {
            //debugger;
            var _args = data;
            if(Rsd.isType(data,Object))
            {
                _args = {};
                _args = Rsd.apply(_args,this.server.data||{});
                _args = Rsd.apply(_args,data||{});
            }
             
            var _ajax = Rsd.create('Rsd.data.Ajax',Rsd.apply({
                    token:Rsd.getAppToken(),
                    appId:Rsd.getAppId(),
                    authCode:Rsd.getAppAuthorization(),
                    jsonFormatter:Rsd.getAppConfig('jsonFormatter'),
                    complete:function _complete(){ if(_waitingId)Rsd.closeWaiting(_waitingId);me.complete.apply(me,arguments);},
                    error:function _error(){ if(_waitingId)Rsd.closeWaiting(_waitingId);me.error.apply(me,arguments);}
                },this.server));
             
            if(_timeout)
            { 
                _ajax.timeout = _timeout;
            }
             
            //参数整理
            //替换路径参数 
            var _url = _ajax.url.toLowerCase(); 
            for(var s in _routeArgs)
            { 
                if(Rsd.isString(s))
                {
                    //console.log(s,_url.indexOf('{'+s.toLowerCase()+'}'));
                    if(_url.indexOf('{'+s.toLowerCase()+'}')>0)
                    {
                        _url = _url.replace('{'+s.toLowerCase()+'}',_routeArgs[s]); 
                        delete _args[s];
                    }
                   
                }
                
            } 
            //从环境变量中匹配路由参数
            if(Rsd.app)
            {
                
                for(var s in Rsd.app.globalVariables)
                { 
                    //console.log(s);
                    if(Rsd.isString(s))
                    {
                        if(_url.indexOf('{'+s.toLowerCase()+'}')>0)
                        {
                            _url = _url.replace('{'+s.toLowerCase()+'}',Rsd.app.globalVariables[s]);  
                        } 
                    }
                }
               
            }            
                       
            _ajax.url = _url;
            //注册事件
            _ajax.on('loadstart',function(evt){me.fire('loadstart',[evt]);});
            _ajax.on('load', function(evt){me.fire('load',[evt]);});
            _ajax.on('loadend',function(evt){me.fire('loadend',[evt]);});
           
            _ajax.on('error', function(evt){me.fire('error',[evt]);});
            _ajax.on('abort', function(evt){me.fire('abort',[evt]);});
            _ajax.on('timeout', function(evt){me.fire('timeout',[evt]);});
             //下载进度
             _ajax.on('progress', function(evt){me.fire('progress',[evt]);});

            //上传时事件
            _ajax.on('uploadloadstart',function(evt){me.fire('uploadloadstart',[evt]);});
            _ajax.on('uploadloadend',function(evt){me.fire('uploadloadend',[evt]);});
            _ajax.on('uploadprogress',function(evt){me.fire('uploadprogress',[evt]);}); 
            _ajax.on('uploadload',function(evt){me.fire('uploadload',[evt]);});
            _ajax.on('uploadtimeout',function(evt){me.fire('uploadtimeout',[evt]);});
            _ajax.on('uploaderror',function(evt){me.fire('uploaderror',[evt]);});
            _ajax.on('uploadabort',function(evt){me.fire('uploadabort',[evt]);});
             
            return _ajax.request(_args,_callback);
        }

    }

},function(type){

    if (!Rsd.data.Service.prototype.hasOwnProperty("events")) {
        var _eventsGetter = function () {
            var _me = this;
            if (_me.__events == null) {
                _me.__events = Rsd.create('Rsd.common.EventList', {});
            }
            return  _me.__events;
        };

        this.defineProperty(type,"events", _eventsGetter, null,true);

    }

    var _localGetter = function () {

        if (this.__local == undefined) {
            this.__local = { method:'get',url:''};
        }
        return this.__local;
    };
    var _localSetter = function (local) {
        if(Rsd.isObject(local))
        {
            Rsd.apply(this.local,local);
        }
        if(Rsd.isString(local))
        {
            this.local.url = local;
        }

    };

    this.defineProperty(type,"local", _localGetter, _localSetter,true);

    var _serverGetter = function () {

        if (this.__server == undefined) {
            this.__server = { timeout:10000,method:'get',url:''};
        }
        return this.__server;
    };

    var _serverSetter = function (server) {
        if(Rsd.isObject(server))
        {
            Rsd.apply(this.server,server);
        }
        if(Rsd.isString(server))
        {
            this.server.url = server;
        }

    };

    this.defineProperty(type,"server", _serverGetter, _serverSetter,true);
});
